package demo.modbus.listener;

import com.serotonin.modbus4j.*;
import com.serotonin.modbus4j.exception.IllegalDataAddressException;
import com.serotonin.modbus4j.exception.ModbusInitException;

import java.util.Random;

/**
 * Created by leohe on 2018/6/19.
 */
public class Test2 {

    static Random random = new Random();
    static float ir1Value = -100;

    public static void main(String[] args) throws Exception{

        ModbusFactory modbusFactory = new ModbusFactory();
        final ModbusSlaveSet listener = modbusFactory.createTcpSlave(false);
        listener.addProcessImage(getModscanProcessImage(1));

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    listener.start();
                }
                catch (ModbusInitException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        while (true) {
            synchronized (listener) {
                listener.wait(200);
            }

            for (ProcessImage processImage : listener.getProcessImages())
                updateProcessImage((BasicProcessImage) processImage);
        }
    }


    static void updateProcessImage(BasicProcessImage processImage) throws IllegalDataAddressException {
        /*processImage.setInput(1, !processImage.getInput(10));
        processImage.setInput(7, !processImage.getInput(13));

        processImage.setNumeric(RegisterRange.INPUT_REGISTER, 20, DataType.FOUR_BYTE_FLOAT, ir1Value += 0.01);

        short hr1Value = processImage.getNumeric(RegisterRange.HOLDING_REGISTER, 80, DataType.TWO_BYTE_BCD)
                .shortValue();
        processImage.setNumeric(RegisterRange.HOLDING_REGISTER, 80, DataType.TWO_BYTE_BCD, hr1Value + 1);*/

        processImage.setHoldingRegister(1, (short) 879);
        processImage.setHoldingRegister(7, (short) 123);
    }

    static class BasicProcessImageListener implements ProcessImageListener {

        int i = 0 ;
        @Override
        public void coilWrite(int offset, boolean oldValue, boolean newValue) {
            System.out.println("Coil at " + offset + " was set from " + oldValue + " to " + newValue);
        }

        @Override
        public void holdingRegisterWrite(int offset, short oldValue, short newValue) {
            // Add a small delay to the processing.
            //            try {
            //                Thread.sleep(500);
            //            }
            //            catch (InterruptedException e) {
            //                // no op
            //            }

            System.out.println("HR(" + i + ") at " + offset + " was set from " + oldValue + " to " + newValue);
            i++;


        }
    }

    static BasicProcessImage getModscanProcessImage(int slaveId) {
        BasicProcessImage processImage = new BasicProcessImage(slaveId);
        //processImage.setAllowInvalidAddress(true);
        processImage.setInvalidAddressValue(Short.MIN_VALUE);

        for (int i = 0 ; i < 10 ; i++) {
            processImage.setHoldingRegister(i, (short) i);
        }


        // Add an image listener.
        processImage.addListener(new BasicProcessImageListener());

        return processImage;
    }
}
